#ifndef _CAMERA_CAMERA_
#define _CAMERA_CAMERA_

#include "../stdafx.h"
#include "BRDFPhoto.h"
#include "../3rdparty/BRDFReader.h"

struct CPoint3D;
struct CPixel;

class CBRDFReader;

class CCamera
{
public:
	CCamera();
	~CCamera();
	
	void CalcIntrinsicParas(int boardWidth, int boardHeight, vector<CString> imagePaths);
	CvMat* GetIntrinsicMatrix();
	CvMat* GetDistortionCoeffs();

	void CameraPoint3D2Pixel(CPoint3D point, CPixel &pixel);
	void Pixel2CameraPoint3D(CPixel pixel, CPoint3D &point);

	void AddNewBRDFPhoto(CBRDFPhoto photo);
	void CalcBRDFPhotoParas();
	void CalcBRDFPhotoParas(int index);
	void InitSampleFromBRDFPhoto(int index);
	void SampleFromBRDFPhoto(int index, float opx, float opy, float opz, float ipx, float ipy);
	CBRDFPhoto GetBRDFPhoto(int index);

	int GetBRDFPhotoCount() {return (int)m_brdfPhotos.size();}
	void CalcBRDF(int sphereSamples, int xRes, int yRes, float xSize, float ySize, int neighbour);
	CBRDFPhoto EvalBRDF(int brdfPhotoIndex);

private:
	CvMat* m_intrinsicMatrix;
	CvMat* m_distortionCoeffs;
	vector<CBRDFPhoto> m_brdfPhotos;
	CBRDFReader m_brdfReader;


	void GetPhotoColor(CColor pColor[], float x, float y, float z);
	void GetPhotoColor(CvMat* ry, CvMat* gy, CvMat* by, float x, float y, float z);
	
	void GetMaterialColor(CColor pColor[], 
		CPoint3D gloPoint,
		CPoint3D samples[],
		int nSamples,
		CBRDFReader* pReader, int index);
	void GetMaterialColor(CColor& color, 
		CPoint3D gloPoint,
		CPoint3D samples[],
		int nSamples,
		CBRDFReader* pReader, int matIndex, int brdfPhotoIndex);

	void FindNearestMaterial(CColor pColor[], CColor* pMaterialColor[], int nPhotos, int colorIndex, int &index, float &weight);

	float Solve(CColor pColor[], CColor* pMaterialColor[], int nPhotos, int nNeighbours, CColor flag[], CColor weight[], CColor pNearestColor[]);
	void FindNeighbour(CvMat* y, CColor* pColor[], int neighbour, int flag[], int color);
	void FillA(CvMat* A, CColor* pColor[], int flag[], int color);
	float SolveX(CvMat* A, CvMat* x, CvMat* y);
	void QuickSort(CPoint3D pArray[], int start, int end);
	void InitConsole();
};

#endif